package crmdna.mail2;

import static crmdna.common.AssertUtils.ensureEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.googlecode.objectify.ObjectifyFilter;
import com.microtripit.mandrillapp.lutung.model.MandrillApiError;

import crmdna.client.Client;
import crmdna.common.Utils;
import crmdna.common.api.APIException;
import crmdna.common.api.APIResponse.Status;
import crmdna.common.contact.ContactProp;
import crmdna.group.Group;
import crmdna.group.Group.GroupProp;
import crmdna.member.Member;
import crmdna.member.MemberLoader;
import crmdna.member.MemberProp;
import crmdna.user.User;
import crmdna.user.User.Action;
import crmdna.user.User.ResourceType;
import crmdna.user.UserCore.UserProp;

public class MailTest {
  private final LocalServiceTestHelper datastoreHelper = new LocalServiceTestHelper(
      new LocalDatastoreServiceTestConfig().setApplyAllHighRepJobPolicy());

  private final String client = "isha";
  private GroupProp sgp;
  private UserProp userWithPermssion;
  private UserProp userWOPermssion;

  @Before
  public void setUp() {
    datastoreHelper.setUp();
    ObjectifyFilter.complete();

    Client.create(client);
    sgp = Group.create(client, "Singapore", User.SUPER_USER);
    assertEquals(1, sgp.groupId);

    Group.addOrDeleteAllowedEmailSender(client, sgp.groupId, "SinGapore@IshayoGa.org",
        "Isha Singapore", true, User.SUPER_USER);
    userWithPermssion =
        User.create(client, "userwithpermission@invalid.com", sgp.groupId, User.SUPER_USER);
    User.addOrDeletePrivilege(client, userWithPermssion.email, ResourceType.GROUP, sgp.groupId,
        Action.SEND_EMAIL, true, User.SUPER_USER);

    userWOPermssion =
        User.create(client, "userwithoutpermission@invalid.com", sgp.groupId, User.SUPER_USER);
  }

  @After
  public void tearDown() {
    ObjectifyFilter.complete();
    datastoreHelper.tearDown();
    System.clearProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL);
  }

  public static void suppressEmailInTestEnv() {
    System.setProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL, "TRUE");
  }

  @Test
  public void sendEmailToNewMember() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");
    String from = "singapore@ishayoga.org";
    suppressEmailInTestEnv();
    List<SentMailEntity> sentMailEntities =
        Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
            from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER);
    ensureEqual(1, sentMailEntities.size());
    ObjectifyFilter.complete();

    SentMailEntity sentMailEntity = Mail.safeGet(client, sentMailEntities.get(0).sentMailId);
    assertEquals(from, sentMailEntity.from);
    assertEquals("sathya.t@ishafoundation.org", sentMailEntity.email);
    MailContentEntity mailContentEntity = MailContent.safeGet(client, sentMailEntity.mailContentId);
    assertEquals("update member profile", mailContentEntity.subject);
    assertEquals("member profile", mailContentEntity.body);


    MemberProp memberProp =
        MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER).toProp();
    assertEquals("Sathya", memberProp.contact.firstName);
    assertEquals("Thilakan", memberProp.contact.lastName);
    assertEquals(1, memberProp.groupIds.size());
    assertTrue(memberProp.groupIds.contains(sgp.groupId));

    Set<String> tags = TagSet.safeGet(client, sentMailEntity.tagSetId).tags;
    assertEquals(2, tags.size());
    assertTrue(tags.contains("singapore"));
    assertTrue(tags.contains("memberprofile"));
  }

  @Test
  public void cannotSendEmailFromInvalidFrom() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    String from = "sathyanarayanant@gmail.com";
    suppressEmailInTestEnv();

    try {
      Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
          from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER);
      assertTrue(false);
    } catch (APIException ex) {
      assertEquals(Status.ERROR_RESOURCE_INCORRECT, ex.statusCode);
    }
  }

  @Test
  public void mailIdShowsNS() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishayoga.org";
    long currentMS = new Date().getTime();

    SentMailEntity sentMailEntity =
        Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
            from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER).get(0);

    final int MILLION = 1000000;
    assertTrue(sentMailEntity.sentMailId >= currentMS * MILLION);
    assertTrue(sentMailEntity.sentMailId < (currentMS + 20) * MILLION);

    ObjectifyFilter.complete();
  }

  @Test
  public void mergeVarsSaved() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishayoga.org";

    SentMailEntity sentMailEntity =
        Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
            from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER).get(0);

    assertEquals(2, sentMailEntity.mergeVars.size());
    assertEquals("Sathya", sentMailEntity.mergeVars.get("FNAME"));
    assertEquals("Thilakan", sentMailEntity.mergeVars.get("LNAME"));

    ObjectifyFilter.complete();
  }

  @Test
  public void sendEmailToExistingMember() throws MandrillApiError, IOException {

    ContactProp contact = new ContactProp();
    contact.asOfyyyymmdd = 20140823;
    contact.email = "sathya.t@ishafoundation.org";
    contact.firstName = "Sathyanarayanan";
    MemberProp sathya = Member.create(client, sgp.groupId, contact, false, User.SUPER_USER);
    assertEquals(1, sathya.memberId);

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    String from = "singapore@ishayoga.org";
    suppressEmailInTestEnv();
    List<SentMailEntity> sentMailEntities =
        Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
            from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER);
    ensureEqual(1, sentMailEntities.size());

    SentMailEntity sentMailEntity = Mail.safeGet(client, sentMailEntities.get(0).sentMailId);
    assertEquals(from, sentMailEntity.from);
    assertEquals("sathya.t@ishafoundation.org", sentMailEntity.email);
    MailContentEntity mailContentEntity = MailContent.safeGet(client, sentMailEntity.mailContentId);
    assertEquals("update member profile", mailContentEntity.subject);
    assertEquals("member profile", mailContentEntity.body);

    MemberProp memberProp =
        MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER).toProp();
    assertEquals(sathya.memberId, memberProp.memberId);

    // first name and last name should not get updated
    assertEquals("Sathyanarayanan", memberProp.contact.firstName);
    assertEquals(null, memberProp.contact.lastName);
    assertEquals(1, memberProp.groupIds.size());
    assertTrue(memberProp.groupIds.contains(sgp.groupId));

    Set<String> tags = TagSet.safeGet(client, sentMailEntity.tagSetId).tags;
    assertEquals(2, tags.size());
    assertTrue(tags.contains("singapore"));
    assertTrue(tags.contains("memberprofile"));
  }

  @Test
  public void isEmailSuppressedTest() {
    assertTrue(!Mail.isEmailSuppressed());

    System.setProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL, "TRUE");
    assertTrue(Mail.isEmailSuppressed());

    System.clearProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL);
    assertTrue(!Mail.isEmailSuppressed());

    System.setProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL, "trUe");
    assertTrue(Mail.isEmailSuppressed());

    System.setProperty(Mail.SYSTEM_PROPERTY_SUPPRESS_EMAIL, "1");
    assertTrue(Mail.isEmailSuppressed());
  }

  @Test
  public void stagsTagIsCaseInsensitive() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishaYoga.org";
    Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
        from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER).get(0);

    ObjectifyFilter.complete();

    MailStatsProp mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("sinGapore"));
    assertEquals(1, mailStatsProp.numRecipientsSendAttempted);
  }

  @Test
  public void multipleStatsTags() throws MandrillApiError, IOException {

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishayoga.org";

    Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
        from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER).get(0);

    Mail.sendBespoke(client, sgp.groupId, emailMap, "registration", "thanks for registration",
        from, Utils.getSet("singapore", "registration"), User.SUPER_USER).get(0);

    EmailMap emailMap2 = new EmailMap();
    emailMap2.add("thulasidhar@gmail.com", "Thulasi", "Thilakan");

    Mail.sendBespoke(client, sgp.groupId, emailMap, "update member profile", "member profile",
        from, Utils.getSet("singapore", "memberprofile"), User.SUPER_USER).get(0);

    ObjectifyFilter.complete();

    MailStatsProp mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("sinGapore"));
    assertEquals(3, mailStatsProp.numRecipientsSendAttempted);

    mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("sinGapore", "Memberprofile"));
    assertEquals(2, mailStatsProp.numRecipientsSendAttempted);

    mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("sinGapore", "registration"));
    assertEquals(1, mailStatsProp.numRecipientsSendAttempted);

    mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("memberProFile"));
    assertEquals(2, mailStatsProp.numRecipientsSendAttempted);
  }

  @Test
  public void nonExistantTags() {
    MailStatsProp mailStatsProp = Mail.getStatsByTag(client, Utils.getSet("sinGapore", "kl"));
    assertEquals(0, mailStatsProp.numRecipientsSendAttempted);
  }

  @Test
  public void mailContentIdSavedCorrectly() throws MandrillApiError, IOException {
    long mailContentId =
        MailContent.create(client, "test 1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;
    assertEquals("test subject", MailContent.safeGet(client, mailContentId).subject);
    assertEquals("test body", MailContent.safeGet(client, mailContentId).body);
    assertEquals("test 1", MailContent.safeGet(client, mailContentId).displayName);

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");
    emailMap.add("thulasidhar@gmail.com", "Thulasidhar", "Kosalram");

    String from = "singapore@ishayoga.org";

    long currentNs = new Date().getTime() * 1000000;
    suppressEmailInTestEnv();
    Mail.send(client, sgp.groupId, emailMap, mailContentId, from,
        Utils.getSet("singapore", "memberprofile"), true, true, userWithPermssion.email);

    ObjectifyFilter.complete();
    SentMailQueryCondition qc = new SentMailQueryCondition();
    qc.mailContentId = mailContentId;

    List<SentMailEntity> sentMailEntities =
        Mail.queryEntitiesSortedByTimeDesc(client, qc, User.SUPER_USER);
    assertEquals(2, sentMailEntities.size());

    SentMailEntity sathyaSentMail;
    SentMailEntity thulasiSentMail;
    if (sentMailEntities.get(0).email.equals("sathya.t@ishafoundation.org")) {
      sathyaSentMail = sentMailEntities.get(0);
      thulasiSentMail = sentMailEntities.get(1);
    } else {
      sathyaSentMail = sentMailEntities.get(1);
      thulasiSentMail = sentMailEntities.get(0);
    }

    SentMailEntity sentMailEntity = sathyaSentMail;
    assertTrue(sentMailEntity.sentMailId >= currentNs);
    assertEquals(mailContentId, sentMailEntity.mailContentId);
    assertTrue(TagSet.safeGet(client, sentMailEntity.tagSetId).tags.contains("singapore"));
    assertTrue(TagSet.safeGet(client, sentMailEntity.tagSetId).tags.contains("memberprofile"));
    assertEquals("Sathya", MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER)
        .toProp().contact.firstName);
    assertEquals("Thilakan", MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER)
        .toProp().contact.lastName);
    assertEquals(
        "sathya.t@ishafoundation.org",
        MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER).toProp().contact.email);

    sentMailEntity = thulasiSentMail;
    assertTrue(sentMailEntity.sentMailId >= currentNs);
    assertEquals(mailContentId, sentMailEntity.mailContentId);
    assertTrue(TagSet.safeGet(client, sentMailEntity.tagSetId).tags.contains("singapore"));
    assertTrue(TagSet.safeGet(client, sentMailEntity.tagSetId).tags.contains("memberprofile"));
    assertEquals(
        "Thulasidhar",
        MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER).toProp().contact.firstName);
    assertEquals("Kosalram", MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER)
        .toProp().contact.lastName);
    assertEquals(
        "thulasidhar@gmail.com",
        MemberLoader.safeGet(client, sentMailEntity.memberId, User.SUPER_USER).toProp().contact.email);
  }

  @Test
  public void repeatEmailNotSentWhenSuppressed() throws MandrillApiError, IOException {
    long mailContentId =
        MailContent.create(client, "test1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;
    assertEquals("test subject", MailContent.safeGet(client, mailContentId).subject);
    assertEquals("test body", MailContent.safeGet(client, mailContentId).body);
    assertEquals("test1", MailContent.safeGet(client, mailContentId).displayName);

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    String from = "singapore@ishayoga.org";

    suppressEmailInTestEnv();
    List<SentMailEntity> entities =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from,
            Utils.getSet("singapore", "memberprofile"), true, true, userWithPermssion.email);
    assertEquals(1, entities.size());
    ObjectifyFilter.complete();

    entities =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from,
            Utils.getSet("isha/singapore", "memberprofile"), true, true, userWithPermssion.email);
    assertEquals(0, entities.size());
  }

  @Test
  public void repeatEmailSentWhenNotSuppressed() throws MandrillApiError, IOException {
    long mailContentId =
        MailContent.create(client, "test1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;
    assertEquals("test subject", MailContent.safeGet(client, mailContentId).subject);
    assertEquals("test body", MailContent.safeGet(client, mailContentId).body);
    assertEquals("test1", MailContent.safeGet(client, mailContentId).displayName);

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    String from = "singapore@ishayoga.org";

    suppressEmailInTestEnv();
    List<SentMailEntity> entities =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from,
            Utils.getSet("singapore", "memberprofile"), false, true, userWithPermssion.email);
    assertEquals(1, entities.size());
    ObjectifyFilter.complete();

    entities =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from,
            Utils.getSet("isha/singapore", "memberprofile"), false, true, userWithPermssion.email);
    assertEquals(1, entities.size());
  }

  @Test
  public void sendEmailWithoutAnyTags() throws MandrillApiError, IOException {
    long mailContentId =
        MailContent.create(client, "test1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;
    assertEquals("test subject", MailContent.safeGet(client, mailContentId).subject);
    assertEquals("test body", MailContent.safeGet(client, mailContentId).body);

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    String from = "singapore@ishayoga.org";

    suppressEmailInTestEnv();
    List<SentMailEntity> entities =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email);
    assertEquals(1, entities.size());
    assertEquals("sathya.t@ishafoundation.org", entities.get(0).email);
    assertEquals(null, entities.get(0).tagSetId);
    ObjectifyFilter.complete();

    SentMailQueryCondition qc = new SentMailQueryCondition();
    qc.email = "sathya.t@ishafoundation.org";

    entities = Mail.queryEntitiesSortedByTimeDesc(client, qc, User.SUPER_USER);
    assertEquals(1, entities.size());
    assertEquals("sathya.t@ishafoundation.org", entities.get(0).email);
    assertTrue(entities.get(0).memberId != null);
    assertEquals(null, entities.get(0).tagSetId);
  }

  @Test
  public void queryByEmail() throws MandrillApiError, IOException, InterruptedException {
    long mailContentId1 =
        MailContent.create(client, "test1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishayoga.org";
    long ts1 = new Date().getTime();
    // send five times
    long sentMailId1 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId1, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId2 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId1, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId3 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId1, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId4 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId1, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId5 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId1, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);

    long ts2 = new Date().getTime();
    assertTrue(ts2 > ts1);

    long mailContentId2 =
        MailContent.create(client, "test2", sgp.groupId, "test subject 2", "test body 2",
            User.SUPER_USER).mailContentId;
    // send mailContentId2 five times
    long sentMailId6 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId2, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId7 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId2, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId8 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId2, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId9 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId2, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);
    long sentMailId10 =
        Mail.send(client, sgp.groupId, emailMap, mailContentId2, from, null, false, true,
            userWithPermssion.email).get(0).sentMailId;
    Thread.sleep(50);

    ObjectifyFilter.complete();

    SentMailQueryCondition qc = new SentMailQueryCondition();
    qc.email = "sathya.t@ishafoundation.org";

    List<SentMailEntity> entities = Mail.queryEntitiesSortedByTimeDesc(client, qc, User.SUPER_USER);
    assertEquals(10, entities.size());

    // should be sorted in descending
    assertEquals(sentMailId10, entities.get(0).sentMailId);
    assertEquals(sentMailId9, entities.get(1).sentMailId);
    assertEquals(sentMailId8, entities.get(2).sentMailId);
    assertEquals(sentMailId7, entities.get(3).sentMailId);
    assertEquals(sentMailId6, entities.get(4).sentMailId);
    assertEquals(sentMailId5, entities.get(5).sentMailId);
    assertEquals(sentMailId4, entities.get(6).sentMailId);
    assertEquals(sentMailId3, entities.get(7).sentMailId);
    assertEquals(sentMailId2, entities.get(8).sentMailId);
    assertEquals(sentMailId1, entities.get(9).sentMailId);

    // include only 3
    qc.numResults = 3;

    entities = Mail.queryEntitiesSortedByTimeDesc(client, qc, User.SUPER_USER);
    assertEquals(3, entities.size());

    assertEquals(sentMailId10, entities.get(0).sentMailId);
    assertEquals(sentMailId9, entities.get(1).sentMailId);
    assertEquals(sentMailId8, entities.get(2).sentMailId);

    // include 6 between ts1 and ts2
    // there are only 5 mails sent between this time
    qc.startMS = ts1;
    qc.endMS = ts2;
    qc.numResults = 6;

    entities = Mail.queryEntitiesSortedByTimeDesc(client, qc, User.SUPER_USER);
    assertEquals(5, entities.size());

    assertEquals(sentMailId5, entities.get(0).sentMailId);
    assertEquals(sentMailId4, entities.get(1).sentMailId);
    assertEquals(sentMailId3, entities.get(2).sentMailId);
    assertEquals(sentMailId2, entities.get(3).sentMailId);
    assertEquals(sentMailId1, entities.get(4).sentMailId);
  }

  @Test
  public void getStatsByMailContent() throws MandrillApiError, IOException, InterruptedException {
    long mailContentId =
        MailContent.create(client, "test1", sgp.groupId, "test subject",
            "test body <a href=\"http:\\www.google.com\">link</a>", User.SUPER_USER).mailContentId;

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    suppressEmailInTestEnv();
    String from = "singapore@ishayoga.org";

    // send five times

    SentMailEntity sentMailEntity =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email).get(0);
    assertEquals(mailContentId, sentMailEntity.mailContentId);

    sentMailEntity =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email).get(0);
    assertEquals(mailContentId, sentMailEntity.mailContentId);

    sentMailEntity =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email).get(0);
    assertEquals(mailContentId, sentMailEntity.mailContentId);

    sentMailEntity =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email).get(0);
    assertEquals(mailContentId, sentMailEntity.mailContentId);

    sentMailEntity =
        Mail.send(client, sgp.groupId, emailMap, mailContentId, from, null, false, true,
            userWithPermssion.email).get(0);
    assertEquals(mailContentId, sentMailEntity.mailContentId);

    ObjectifyFilter.complete();

    MailStatsProp mailStatsProp =
        Mail.getStatsByMailContent(client, mailContentId, userWithPermssion.email);
    assertEquals(5, mailStatsProp.numRecipientsSendAttempted);
    assertEquals(1, mailStatsProp.urlVsNumRecipientsThatClicked.size());
    assertEquals(0, mailStatsProp.urlVsNumRecipientsThatClicked.get("http:\\www.google.com")
        .intValue());

  }

  @Test(expected = APIException.class)
  public void permissionRequiredToSendEmail() throws MandrillApiError, IOException {
    long mailContentId =
        MailContent.create(client, "test1", sgp.groupId, "test subject", "test body",
            User.SUPER_USER).mailContentId;

    EmailMap emailMap = new EmailMap();
    emailMap.add("sathya.t@ishafoundation.org", "Sathya", "Thilakan");

    Mail.send(client, sgp.groupId, emailMap, mailContentId, "singapore@ishayoga.org", null, true,
        true, userWOPermssion.email);
  }

  @Test
  public void memberCreatedWhenFlagSet() {
    assertTrue(false);
  }

  @Test
  public void memberNotCreatedWhenFlagNotSet() {
    assertTrue(false);
  }
}
